package xyz.ck.commons.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collection;

public abstract class StringUtil {

	/**
	 * Convert String first Charator to UpperCase.For example: "user" --> "User"
	 * 
	 * @param paramString
	 * @return
	 */
	public static String toTitle(String paramString) {
		if (paramString == null || paramString.isEmpty()) {
			return paramString;
		}
		char[] array = paramString.toCharArray();
		char firstChar = array[0];
		array[0] = Character.toUpperCase(firstChar);
		return new String(array);
	}

	/**
	 * Convert String first Charator to LowerCase.For example: "User" --> "user"
	 * 
	 * @param paramString
	 * @return
	 */
	public static String unTitle(String paramString) {
		if (paramString == null || paramString.isEmpty()) {
			return paramString;
		}
		char[] array = paramString.toCharArray();
		char firstChar = array[0];
		array[0] = Character.toLowerCase(firstChar);
		return new String(array);
	}

	/**
	 * 
	 * @param param
	 * @return
	 */
	public static String toUpperCase(String param) {
		if (param == null || param.isEmpty()) {
			return param;
		}
		return param.toUpperCase();
	}

	/**
	 * 
	 * @param param
	 * @return
	 */
	public static String toLowerCase(String param) {
		if (param == null || param.isEmpty()) {
			return param;
		}
		return param.toLowerCase();
	}

	/**
	 * 
	 * native2ascii.exe Java code implementation.
	 * 
	 * 
	 * 
	 * @author
	 * 
	 * @version 1.0
	 */

	/**
	 * 
	 * prefix of ascii string of native character
	 */

	private static String PREFIX = "\\u";

	/**
	 * Native to ascii string. It's same as execut native2ascii.exe.
	 * 
	 * @param str
	 * @return
	 */
	public static String native2Ascii(String str) {
		char[] chars = str.toCharArray();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < chars.length; i++) {
			sb.append(char2Ascii(chars[i]));
		}
		return sb.toString();

	}

	/**
	 * Native character to ascii string.
	 * 
	 * @param c
	 * @return
	 */
	private static String char2Ascii(char c) {
		if (c > 255) {
			StringBuilder sb = new StringBuilder();
			sb.append(PREFIX);
			int code = (c >> 8);
			String tmp = Integer.toHexString(code);
			if (tmp.length() == 1) {
				sb.append("0");
			}
			sb.append(tmp);
			code = (c & 0xFF);
			tmp = Integer.toHexString(code);
			if (tmp.length() == 1) {
				sb.append("0");
			}
			sb.append(tmp);
			return sb.toString();
		} else {
			return Character.toString(c);
		}
	}

	/**
	 * Ascii to native string. It's same as execut native2ascii.exe -reverse.
	 * 
	 * @param str
	 * @return
	 */
	public static String ascii2Native(String str) {

		StringBuilder sb = new StringBuilder();
		int begin = 0;
		int index = str.indexOf(PREFIX);
		while (index != -1) {
			sb.append(str.substring(begin, index));

			sb.append(ascii2Char(str.substring(index, index + 6)));

			begin = index + 6;

			index = str.indexOf(PREFIX, begin);
		}
		sb.append(str.substring(begin));
		return sb.toString();

	}

	/**
	 * Ascii to native character.
	 * 
	 * @param str
	 * @return
	 */
	private static char ascii2Char(String str) {

		if (str.length() != 6) {
			throw new IllegalArgumentException(
					"Ascii string of a native character must be 6 character.");
		}

		if (!PREFIX.equals(str.substring(0, 2))) {
			throw new IllegalArgumentException(
					"Ascii string of a native character must start with \"\\u\".");
		}
		String tmp = str.substring(2, 4);
		int code = Integer.parseInt(tmp, 16) << 8;
		tmp = str.substring(4, 6);
		code += Integer.parseInt(tmp, 16);
		return (char) code;
	}

	public static String defaultEncoding = System.getProperty("file.encoding");

	public static String encode(String string) {
		return encode(string, defaultEncoding);
	}

	public static String encode(String string, String enc) {

		try {
			return URLEncoder.encode(string, enc);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return string;
		}
	}

	/**
	 * 
	 * @param <T>
	 * @param
	 * @param div
	 * @param objs
	 * @return
	 */
	public static <T> String joins(String div, T[] objs) {
		if (objs == null)
			return "null";
		int iMax = objs.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(objs[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, String... strs) {
		if (strs == null)
			return "null";
		int iMax = strs.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(strs[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	/**
	 * 
	 * @param
	 * @param div
	 * @param objs
	 * @return
	 */
	public static String joins(String div, Collection<?> objs) {
		if (objs == null)
			return "null";
		StringBuilder b = new StringBuilder();

		int iMax = objs.size() - 1;
		if (iMax == -1)
			return "";
		int i = 0;
		for (Object obj : objs) {

			b.append(obj);
			if (i == iMax)
				break;
			b.append(div);
			i++;
		}
		return b.toString();
	}

	public static String joins(String div, int[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, short[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, boolean[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, long[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, double[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, char[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, float[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String joins(String div, byte[] array) {
		if (array == null)
			return "null";
		int iMax = array.length - 1;
		if (iMax == -1)
			return "";
		StringBuilder b = new StringBuilder();
		for (int i = 0;; i++) {
			b.append(array[i]);
			if (i == iMax)
				return b.toString();
			b.append(div);
		}
	}

	public static String decode(String string) {
		return decode(string, defaultEncoding);
	}

	public static String decode(String string, String enc) {

		try {
			return URLDecoder.decode(string, enc);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return string;
		}
	}

	/**
	 * join Continuous space Char for Console format
	 * 
	 * @param source
	 * @return
	 */
	public static String trimAllSpace(String source) {
		if (source == null) {
			return source;
		}
		return source.trim().replaceAll("\\s+", " ");
	}

	/**
	 * 
	 * eg : test --> %test% <br/>
	 * eg2: test* -- test% <br/>
	 * eg3: test*123*test --> test%123%test
	 * 
	 * @param str
	 * @return
	 */
	public static String resolveFuzzyQuery(String str) {
		if (str == null || str.isEmpty()) {
			return str;
		}
		str = str.trim();
		if (str.indexOf("*") > -1) {
			return str.replaceAll("\\*", "%");
		} else {
			str = "%" + str + "%";
			return str;
		}
	}

	public static String resolveRegPattern(String str) {
		if (str == null || str.isEmpty()) {
			return str;
		}
		str = str.trim();
		if (str.indexOf("*") > -1) {
			return str.replaceAll("\\*", ".*");
		} else {
			str = ".*" + str + ".*";
			return str;
		}
	}

}
